#coding=utf-8
import sys,os,time,types,threading as th
from Gui.QQ import Ui_QQForm,Ui_QQ_veritycode,Ui_qqMain,Ui_qqMsg,Ui_qqGroupMsg
from PyQt4 import QtCore,QtGui
from api import getface,QQ_class,cmsg,app as ahh,poll
#cxfreeze打包时使用
#import Api_webqq
#返回消息
class abmsg(th.Thread):
    def __init__(self):
        th.Thread.__init__(self)
    def run(self):
        while True:
            AppQQ_main._poll()
            time.sleep(0.5)
#图标获取
class abface(th.Thread):
    def __init__(self):
        th.Thread.__init__(self)
    def run(self):
        getface.getfacemethod(myclass,mydata)
#消息处理
class abbox(th.Thread):
    def __init__(self):
        th.Thread.__init__(self)
    def run(self):
        #[{u'retcode': 102, u'errmsg': u''}]
        yy,main,xx,zz = AppQQ_main.uuii()
        msgnum = 0
        while True:
            msgnum +=1
            msg = mydata.get('msg','messagebox') #获取消息盒子
            #print msg
            if type(msg) == types.ListType and len(msg) >0:
                #print msg
                for i in msg:
                    try:
                        if i['retcode'] ==0:
                            if len(i['result']) == 0:
                                ahh.removemsg(msg,i,mydata)
                            for e in i['result']:
                                if e['poll_type'] == u'buddies_status_change': #状态
                                    if mydata.get('face','thread').empty() == True:
                                        poll.Status.status(yy,zz,e,main)
                                        ahh.removemsg(i['result'],e,mydata)
                                    continue
                                elif e['poll_type'] == u'group_message': #群消息
                                    if xx[e['value']['group_code']].has_key('msgobject'):
                                        if xx[e['value']['group_code']]['msgobject'].isHidden() == False:
                                            if xx[e['value']['group_code']]['msgobject'].data.has_key('err'):
                                                gid = e['value']['send_uin']
                                            else:
                                                try:
                                                    gid = xx[e['value']['group_code']]['msgobject'].t[e['value']['send_uin']]['nick']
                                                except AttributeError:
                                                    gid = e['value']['send_uin']
                                            poll.Status.group_message_add(cmsg,myclass,mydata,e['value'],xx[e['value']['group_code']]['msgobject'],gid,e['value']['content'],e['value']['time'])
                                            ahh.removemsg(i['result'],e,mydata)
                                            #poll.Status.messagegroup_box_del(mydata,e['value']['group_code'])
                                            continue
                                    poll.Status.messagegroup_box(mydata,e['value']['group_code'])
                                elif e['poll_type'] == u'message': #消息
                                    if yy[e['value']['from_uin']].has_key('msgobject'):
                                        if yy[e['value']['from_uin']]['msgobject'].isHidden() == False:
                                            #显示窗口时加载的消息，并删除消息盒子中的数据
                                            poll.Status.message_add(cmsg,myclass,mydata,e['value'],yy[e['value']['from_uin']]['msgobject'],yy[e['value']['from_uin']]['nick'],e['value']['content'],e['value']['time'])
                                            ahh.removemsg(i['result'],e,mydata)
                                            #poll.Status.message_box_del(mydata,e['value']['from_uin'])
                                            continue
                                    poll.Status.message_box(mydata,e['value']['from_uin'])
                                elif e['poll_type'] == u'input_notify':
                                    ahh.removemsg(i['result'],e,mydata)
                                else:
                                    print >> mydata.get('log','debug'),e
                                    ahh.removemsg(i['result'],e,mydata)
                        elif i['retcode'] ==102:
                            msg.remove({u'retcode': 102, u'errmsg': u''})
                        elif i['retcode'] ==106:
                            msg.remove(i)
                        else:
                            print >> mydata.get('log','debug'),i
                            msg.remove(i)
                    except KeyError:
                        try:
                            msg.remove(i)
                        except ValueError as kk:
                            print >> mydata.get('log','debug'),kk
            time.sleep(0.5)

#login class
class AppQQ_login(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.loginGui()
    def loginGui(self):
        self.ui = Ui_QQForm() #qq login
        self.ui.setupUi(self)
        #self.ui.pswd.setEchoMode(QtGui.QLineEdit.Password)
        self.connect(self.ui.login,QtCore.SIGNAL('clicked()'),self.loginAction)
        self.show()
    def loginAction(self):
        qq = myclass.Login(self.ui.qq.displayText(),self.ui.pswd.displayText())
        if qq  == -1:
            mydata.set('t',-1,'status')
        elif qq == 1: #你输入的帐号或者密码不正确，请重新输入
            mydata.set('t',1,'status')
        elif qq == 2: #登录失败
            mydata.set('t',2,'status')
        elif qq ==3: #验证码
            mydata.set('veritycode',AppQQ_veritycode(),'gui')
            mydata.set('qq',self.ui.qq.displayText())
            mydata.set('pswd',self.ui.qq.displayText())
        elif qq ==103:
            mydata.set('t',103,'status')
        else:
            mydata.set('qq',self.ui.qq.displayText())
            mydata.set('pswd',self.ui.qq.displayText())
            mydata.set('t',200,'status') #设置在线状态
            mydata.set('info',qq['result']) #登陆返回session值
            mydata.set('qq_info',myclass.get_info()) #qq个人信息
            mydata.set('online',myclass.get_online()) #qq在线好友
            mydata.set('friends',myclass.get_user_friends()) #qq好友列表
            mydata.set('group',myclass.get_group_name_list()) #qq群组
            mydata.set('login',self,'gui')
        if mydata.get('t','status') == 200:
            self.close()
            mydata.set('main',AppQQ_main(),'gui')
            AppQQ_main.mainAction()
        elif mydata.get('t','status') == -1:
            QtGui.QMessageBox.information(self, u"警告",
                    u"你输入的帐号或者密码不正确，请重新输入！" )
        elif mydata.get('t','status') == 1:
            QtGui.QMessageBox.information(self, u"警告",
                    u"登录失败！" )
        elif mydata.get('t','status') == 103:
            QtGui.QMessageBox.information(self, u"警告",
                    u"您的QQ帐号受到临时登录限制！")
#veritycode class
class AppQQ_veritycode(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.veritycodeGui()
    def veritycodeGui(self):
        self.ui = Ui_QQ_veritycode()
        self.ui.setupUi(self)
        self.connect(self.ui.codeenter,QtCore.SIGNAL('clicked()'),self.veritycodeAction)
        self.show()
    def veritycodeAction(self):
        myclass.getG().Login(mydata.get('qq'),mydata.get('pswd')) #设置qq号和密码
        myclass.getG().setverifycode(self.ui.veritycode.displayText()) #设置验证码
        qq = myclass.getG().verityLogin() #验证登陆
        if qq  == -1:
            mydata.set('t',-1,'status')
        elif qq == 1: #你输入的帐号或者密码不正确，请重新输入
            mydata.set('t',1,'status')
        elif qq == 2: #登录失败
            mydata.set('t',2,'status')
        else:
            mydata.set('qq',self.ui.qq.displayText())
            mydata.set('pswd',self.ui.qq.displayText())
            mydata.set('t',200,'status') #设置在线状态
            mydata.set('info',qq['result']) #登陆返回session值
            mydata.set('qq_info',myclass.get_info()) #qq个人信息
            mydata.set('online',myclass.get_online()) #qq在线好友
            mydata.set('friends',myclass.get_user_friends()) #qq好友列表
            mydata.set('group',myclass.get_group_name_list()) #qq群组
        self.close()
        if mydata.get('t','status') == 200:
            mydata.set('main',AppQQ_main(),'gui')
#main class
class AppQQ_main(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        mydata.set('msg',[],'messagebox')
        #print 1
        #print mydata.get('msg','messagebox')
        self.mainGui()
        #self.mainAction()
    def mainGui(self):
        mydata.get('friends')['result']['categories'].insert(0,{u'sort': 0, u'index': 0, u'name': u'我的好友'})
        self.ui = Ui_qqMain()
        self.ui.setupData(mydata)
        self.ui.sortList()
        self.ui.Groupsortlist()
        self.ui.setupUi(self)
        self.show()
        self.createIcon()

        self.ui.treeqq.connect(self.ui.treeqq,QtCore.SIGNAL("sortsignal(int)"), self.ui.sortsignal) #paixu
        self.ui.treeqq.connect(self.ui.treeqq,QtCore.SIGNAL("triggleface"), self.ui.triggleface) #touxiang
        self.ui.treeqq.connect(self.ui.treeqq,QtCore.SIGNAL("trigglegface"), self.ui.trigglegface)
        self.ui.treeqq.connect(self.ui.treeqq,QtCore.SIGNAL("qqface"), self.ui.qqface) #xiaoxi
        self.ui.treeqq.connect(self.ui.treeqq,QtCore.SIGNAL("qqgface"), self.ui.qqgface) #groupxiaoxi
        self.connect(self.ui.treeqq, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.click)
        self.connect(self.ui.groupqq, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.groupclick)
        self.connect(self.ui.qqstatus, QtCore.SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.click)
    def click(self,q,i):
        try:
            if q.info is not None:
                if q.info.has_key('msgobject') is False:
                    q.info['msgobject'] = AppQQ_msg()
                    q.info['msgobject'].loadinfoAction(q.info)
                else:
                    if q.info['msgobject'].data.has_key('err'):
                        del q.info['msgobject'].data['err']
                        q.info['msgobject'].loadinfoAction(q.info)
                    q.info['msgobject'].show()
                poll.Status.message_box_del(mydata,q.info['uin'])
                self.ui.treeqq.emit(QtCore.SIGNAL("qqface"),q.info['uin'],q.info['categories'],q.info['img'])
                zz = mydata.get('sorttype')
                q.info['object'].parent().setText(0,u"{name}({online}/{count})".format(name=zz[q.info['categories']]['name'],count=zz[q.info['categories']]['count'],online=zz[q.info['categories']]['online']))
                del zz
        except AttributeError as t:
            print >> mydata.get('log','debug'),t
    def groupclick(self,q,i):
        try:
            if q.info is not None:
                if q.info.has_key('msgobject') is False:
                    q.info['msgobject'] = AppQQ_group_msg()
                    q.info['msgobject'].loadinfoAction(q.info)
                else:
                    if q.info['msgobject'].data.has_key('err'):
                        del q.info['msgobject'].data['err']
                        q.info['msgobject'].loadinfoAction(q.info)
                    q.info['msgobject'].show()
                poll.Status.messagegroup_box_del(mydata,q.info['code'])
                self.ui.treeqq.emit(QtCore.SIGNAL("qqgface"), q.info['code'],q.info['img'])
        except AttributeError as t:
            print >> mydata.get('log','debug'),t
    def createAction(self):
        #QtGui.qApp.quit
        self.quitAction = QtGui.QAction("&Quit", self,triggered=self.mainexec)
    def createIcon(self):
        self.createAction()
        self.trayIconMenu = QtGui.QMenu(self)
        self.trayIconMenu.addAction(self.quitAction)
        self.barIcon = QtGui.QSystemTrayIcon(self)
        self.barIcon.setContextMenu(self.trayIconMenu)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap('ico/qq.jpg'))
        self.barIcon.setIcon(icon)
        self.barIcon.show()
        self.barIcon.activated.connect(self.showmain)
    def showmain(self,reason):
        if reason in (QtGui.QSystemTrayIcon.Trigger, QtGui.QSystemTrayIcon.DoubleClick):
            if self.isHidden():
                self.show()
    def closeEvent(self, event):
        self.mainexec()
        event.ignore()
    def showEvent(self, event):
        if self.windowType() == QtCore.Qt.Tool:
            self.setWindowFlags(QtCore.Qt.Window)
            self.show()
        event.ignore()
    def changeEvent(self, event):
        if event.type() == QtCore.QEvent.WindowStateChange and self.isMinimized():
            self.setWindowFlags(QtCore.Qt.Tool)
            self.hide()
            event.ignore()
    def mainexec(self):
        app.quit()
    @staticmethod
    def uuii():
        yy = {}
        main = mydata.get('main','gui')
        for y in mydata.get('sortlist'):
            for u in mydata.get('sortlist')[y]:
                yy[u] = mydata.get('sortlist')[y][u]
        xx = mydata.get('groupsortlist')
        zz = mydata.get('sorttype')
        return yy,main,xx,zz
    @staticmethod
    def mainAction():
        #加了setDaemon会卡，不知道是不是这个原因，要跟踪
        #消息回收
        a = abmsg()
        a.setDaemon(True)
        a.start()
        #AppQQ_main._poll()
        #头像获取
        b = abface()
        b.setDaemon(True) #这里可以不要守护线程
        b.start()
        #消息处理
        d = abbox()
        d.setDaemon(True)
        d.start()
        yy,main,xx,zz = AppQQ_main.uuii()
        mm = th.Thread(target=AppQQ_main.message_mm,args=(xx,zz,yy,main))
        mm.setDaemon(True)
        mm.start()
        mg = th.Thread(target=AppQQ_main.message_mg,args=(xx,main))
        mg.setDaemon(True)
        mg.start()
    @staticmethod
    def _poll():
        msg = myclass.poll()
        mydata.get('msg','messagebox').append(msg)
        """
        if type(msg) == types.DictionaryType and msg.has_key('result'):
            for e in msg['result']:
                if e['poll_type'] == u'buddies_status_change': #状态
                    sound.global_()
                elif e['poll_type'] == u'group_message': #群消息
                    sound.msg()
                elif e['poll_type'] == u'message': #消息
                    sound.msg()
        """
    @staticmethod
    def _get_tip():
        myclass.get_tip()
        t2 = th.Timer(60,AppQQ_main._get_tip)
        t2.start()
    @staticmethod
    def message_mm(*t):
        xx,zz,yy,main = t
        msgnum = 1
        while True:
            msgnum +=1
            m = mydata.get('message','messagebox')
            for i in m:
                poll.Status.message(msgnum,main,yy,zz,i)
            time.sleep(1)
        pass
    @staticmethod
    def message_mg(*t):
        xx,main = t
        msgnum = 1
        while True:
            msgnum +=1
            m = mydata.get('messagegroup','messagebox')
            for i in m:
                poll.Status.group_message(msgnum,main,xx,i)
                pass
            time.sleep(1)
#Ui_qqMsg
class AppQQ_msg(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.msgGui()
        pass
    def msgGui(self):
        self.ui = Ui_qqMsg()
        self.ui.setupUi(self)
        self.show()
        self.ui.close.connect(self.ui.close, QtCore.SIGNAL("clicked()"), self.msgclose)
        self.ui.ok.connect(self.ui.ok, QtCore.SIGNAL("clicked()"), self.msgAction)
        self.connect(self, QtCore.SIGNAL("load()"), self.load)
        self.ui.msg.connect(self.ui.msg, QtCore.SIGNAL("add"), self.add)
        self.connect(self,QtCore.SIGNAL("send()"),self.sendmessage)
        pass
    def msgclose(self):
        self.hide()
    def closeEvent(self, event):
            self.hide()
            event.ignore()
    def msgAction(self):
        th.Thread(target=self.sending).start()
        #self.emit(QtCore.SIGNAL("send()"))
    def sending(self):
        self.emit(QtCore.SIGNAL("send()"))
    def sendmessage(self):
        msg = cmsg.sendmsg(self.ui.comment.toPlainText())
        a = myclass.getG().send_message(self.data['uin'],msg)

        if type(a) == types.DictionaryType:
            if a['result'] == u'ok':
                msg = cmsg.convertmsg(self.ui.comment.toPlainText())
                html = cmsg.formathtml(mydata.get('qq_info')['result']['nick'],time.strftime(cmsg.s),msg)
                self.ui.comment.setPlainText('')
                self.ui.msg.append(html)
                del html
        del msg,a
    def loadinfoAction(self,data):
        self.data = data
        self.setObjectName(str(data['uin']))
        #self.data['msgobject'] = self
        th.Thread(target=self.getdata).start()
        image = QtGui.QImage(self.data['img'])
        if not image.isNull():
            self.ui.img.setPixmap(QtGui.QPixmap.fromImage(image))
        else:
            self.ui.img.setPixmap(QtGui.QPixmap('ico/qq.jpg'))
        del image
    def load(self):
        self.ui.info.setText(self.data['lnick'])
        qq = u'QQ:{0}({1})'.format(self.data['qq'],self.data['nick'])
        self.ui.qq.setText(qq)
        self.setWindowTitle(qq)
        del qq
    def getdata(self):
        try:
            self.data['lnick'] = myclass.getG().get_nick(self.data['uin'])['result'][0]['lnick'] #获取qq签名
            if self.data.has_key('qq') == False:
                self.data['qq'] = myclass.getG().get_friend_uin2(self.data['uin'],1)['result']['account'] #获取好友qq号
        except Exception:
            self.data['lnick'] = ''
            self.data['qq'] = 0
            self.data['err'] = True
        self.emit(QtCore.SIGNAL("load()"))
    def add(self,html):
        self.ui.msg.append(html)
        self.ui.msg.moveCursor(11)
#Ui_GROUP_MSG
class AppQQ_group_msg(QtGui.QMainWindow):
    def __init__(self,parent=None):
        QtGui.QWidget.__init__(self,parent)
        self.msgGui()
        pass
    def msgGui(self):
        self.ui = Ui_qqGroupMsg()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.show()
        self.ui.close.connect(self.ui.close, QtCore.SIGNAL("clicked()"), self.msgclose)
        self.ui.ok.connect(self.ui.ok, QtCore.SIGNAL("clicked()"), self.msgAction)
        self.connect(self, QtCore.SIGNAL("load()"), self.load)
        self.ui.msg.connect(self.ui.msg, QtCore.SIGNAL("add"), self.add)
        self.connect(self,QtCore.SIGNAL("send()"),self.sendmessage)
        pass
    def msgclose(self):
        self.hide()
    def closeEvent(self, event):
            self.hide()
            event.ignore()
    def msgAction(self):
        th.Thread(target=self.sending).start()
        #self.emit(QtCore.SIGNAL("send()"))
    def sending(self):
        self.emit(QtCore.SIGNAL("send()"))
    def sendmessage(self):
        msg = cmsg.sendmsg(self.ui.comment.toPlainText())
        a = myclass.getG().send_group_message(self.data['gid'],msg)
        if type(a) == types.DictionaryType:
            if a['result'] == u'ok':
                msg = cmsg.convertmsg(self.ui.comment.toPlainText())
                html = cmsg.formathtml(mydata.get('qq_info')['result']['nick'],time.strftime(cmsg.s),msg)
                self.ui.comment.setPlainText('')
                self.ui.msg.append(html)
                del html
        del msg,a
    def loadinfoAction(self,data):
        self.data = data
        self.setObjectName(str(data['code']))
        th.Thread(target=self.getdata).start()
        image = QtGui.QImage(self.data['img'])
        if not image.isNull():
            self.ui.img.setPixmap(QtGui.QPixmap.fromImage(image))
        else:
            self.ui.img.setPixmap(QtGui.QPixmap('ico/qq.jpg'))
        del image
    def setmemberlist(self):
        t = {}
        for i in self.data['grouplist']['minfo']:
            t[i['uin']] = {}
            if self.data['grouplist'].has_key('cards'):
                for e in self.data['grouplist']['cards']:
                    if e['muin'] == i['uin']:
                        i['nick'] = ':'+e['card']
            t[i['uin']] = i
            item = QtGui.QListWidgetItem(self.ui.grouplist)
            item.setText(i['nick'])
            item.setIcon(QtGui.QIcon('ico/qq.jpg'))
        self.ui.pushButton.setText(u"群友({online}/{count})".format(count = len(self.data['grouplist']['minfo']),online = len(self.data['grouplist']['stats'])))
        self.t = t
        del t
    def load(self):
        #self.ui.info.setText(self.data['group']) #群说明
        qq = u'群:{0}({1})'.format(self.data['name'],self.data['qqgroup'])
        self.ui.qqgroup.setText(qq)
        self.setWindowTitle(qq)
        if self.data.has_key('err') == False:
            self.setmemberlist()
        del qq
    def getdata(self):
        try:
            if self.data.has_key('qqgroup') == False:
                self.data['qqgroup'] = myclass.getG().get_friend_uin2(self.data['code'])['result']['account'] #群号
            self.data['grouplist'] = myclass.getG().get_group_info_ext2(self.data['code'])['result']
        except Exception:
            self.data['qqgroup'] = 0
            self.data['grouplist'] = []
            self.data['err'] = True
        self.emit(QtCore.SIGNAL("load()"))
    def add(self,html):
        self.ui.msg.append(html)
        self.ui.msg.moveCursor(11)
#中间件 class
class QQ_DATA(object):
    dict = {'qq':{}}
    #ns as namespace
    def __init__(self):
        pass
    def get(self,key,ns=None):
        if ns is None:
            k = self.dict['qq'][key]
        else:
            try:
                k = self.dict[ns][key]
            except KeyError:
                return '-1None'
        return k
        pass
    def set(self,key,value,ns=None):
        if ns is None:
            self.dict['qq'][key] = value
        else:
            try:
                self.dict[ns][key] = value
            except KeyError:
                self.dict[ns] = {}
                self.dict[ns][key] = value
        pass
#controller class
if __name__ =='__main__':
    t = file('debug','wb')
    mydata = QQ_DATA() #中间件
    mydata.set('message',set([]),'messagebox')
    mydata.set('messagegroup',set([]),'messagebox')
    mydata.set('log',t,'debug')
    sound = poll.Sound()
    myclass = QQ_class.QQ_CLASS(mydata) #qq class
    app = QtGui.QApplication(sys.argv)
    myqq = AppQQ_login() #qq gui
    sys.exit(app.exec_())
